package com.pactera.madp.cp.controller.oms.prod;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.common.log.annotation.SysLog;
import com.pactera.madp.common.security.annotation.Inner;
import com.pactera.madp.cp.api.dto.prod.ProdDto;
import com.pactera.madp.cp.api.entity.prod.ProdDepositEntity;
import com.pactera.madp.cp.api.entity.prod.ProdEntity;
import com.pactera.madp.cp.common.enums.ProductGroupEnum;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.service.ProdService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 华融湘江产品管理
 *
 * @author HuHao
 * @date 2022/3/16 9:31
 */
@RestController
@AllArgsConstructor
@RequestMapping("/prod")
@Api(value = "prod", tags = "产品管理")
public class ProdController {

    @Autowired
    private ProdService prodService;

    @GetMapping("/group-tree")
    @ApiOperation(value = "查询产品树")
    public R getProdTree() {
        return R.ok(prodService.getProdGroupTree());
    }

    @GetMapping("/deposit-list")
    @ApiOperation(value = "查询存款列表")
    public R getDeposits(Integer type) {
        return R.ok(prodService.getDeposits(type));
    }

    @SysLog("编辑存款")
    @PutMapping("/deposit-edit")
    @ApiOperation(value = "编辑存款")
    public R updateDeposit(@RequestBody ProdDepositEntity entity) {
        return prodService.updateDeposit(entity);
    }

    @GetMapping("/prod-list")
    @ApiOperation(value = "获取产品列表")
    public R<List<ProdEntity>> getProdList(Integer type) {
        return R.ok(prodService.getProdList(type));
    }

    @GetMapping("/prod-page")
    @ApiOperation(value = "分页获取产品列表")
    public R<IPage<ProdEntity>> getProdPage(
            @RequestParam(required = false) String code,
            @RequestParam(required = false) String name,
            Integer type,
            @RequestParam(required = false) Integer state,
            Page page
    ) {
        Integer corpId = CorpContextHolder.getCorpId();
        LambdaQueryWrapper<ProdEntity> wrapper = Wrappers.<ProdEntity>lambdaQuery()
                .eq(ProdEntity::getType, type)
                .eq(ProdEntity::getCorpId, corpId);
        if (state != null && state == 1) {
            // 已发布
            wrapper.eq(ProdEntity::getState, 2);
        } else {
            List<Integer> list = new ArrayList<>();
            // 未编辑
            list.add(0);
            // 未发布
            list.add(1);
            // 待审批
            list.add(3);
            // 已驳回
            list.add(4);
            wrapper.in(ProdEntity::getState, list);
        }
        if (code != null && !code.isEmpty())
            wrapper.like(ProdEntity::getCode, code);
        if (name != null && !name.isEmpty())
            wrapper.like(ProdEntity::getName, name);
        wrapper.orderByAsc(ProdEntity::getPrdStatus);
        wrapper.orderByAsc(ProdEntity::getCode);
        wrapper.orderByDesc(ProdEntity::getState);
        wrapper.orderByAsc(ProdEntity::getSort);
        IPage<ProdEntity> page1 = prodService.page(page, wrapper);
        return R.ok(page1);
    }

    @GetMapping
    @ApiOperation(value = "获取产品信息")
    public R getProd(Integer prodId) {
        ProdDto prodDto = prodService.getProd(prodId);
        return R.ok(prodDto);
    }

    // 只有2-活动、4-贷款、5-信用卡可新增
    @SysLog("新增产品-活动/贷款/信用卡")
    @PostMapping
    @ApiOperation(value = "新增产品")
    public R saveProd(@RequestBody ProdDto entity) {
        Integer type = entity.getType();
        if (type == null || (
                !type.equals(ProductGroupEnum.ACTIVITY.getCode())
                        && !type.equals(ProductGroupEnum.LOAN.getCode())
                        && !type.equals(ProductGroupEnum.CREDITCARD.getCode())
        ))
            return R.failed("产品类型不在可新增的产品类型范围[2-活动、4-贷款、5-信用卡]内");
        String code = entity.getCode();
        Integer count = prodService.count(
                Wrappers.<ProdEntity>lambdaQuery()
                .eq(ProdEntity::getCode, code)
                .eq(ProdEntity::getCorpId, CorpContextHolder.getCorpId())
        );
        if (count != null && count > 0)
            return R.failed(StrUtil.format("产品编码为:{}的产品已存在，不可反复添加", code));
        String name = entity.getName();
        count = prodService.count(
                Wrappers.<ProdEntity>lambdaQuery()
                        .eq(ProdEntity::getName, name)
                        .eq(ProdEntity::getCorpId, CorpContextHolder.getCorpId())
        );
        if (count != null && count > 0)
            return R.failed(StrUtil.format("名称为:{}的产品已存在，不可反复添加", name));

        ProdEntity prodEntity = new ProdEntity();
        BeanUtil.copyProperties(entity, prodEntity);
        prodEntity.setState(1);
        /*prodEntity.setState(0);
        if (type.equals(ProductGroupEnum.LOAN.getCode()) || type.equals(ProductGroupEnum.CREDITCARD.getCode())) {
            prodEntity.setState(1);
        }*/
        List<Integer> deptIds = entity.getDeptIds();
        if (deptIds == null || deptIds.isEmpty()) {
            return R.failed("请选择部门可见范围");
        }
        return R.ok(prodService.saveProd(prodEntity, deptIds));
    }

    @SysLog("编辑产品")
    @PutMapping
    @ApiOperation(value = "编辑产品")
    public R updateProd(@RequestBody ProdDto entity) {
        ProdEntity localEntity = prodService.getById(entity.getId());
//        checkEndTime(entity.getEndTime());
        if (localEntity.getState() != null && localEntity.getState().equals(2)) {
            throw new CheckedException("已发布/上架产品不可编辑，须先下架");
        }
        ProdEntity prodEntity = new ProdEntity();
        BeanUtil.copyProperties(entity, prodEntity);
        List<Integer> deptIds = entity.getDeptIds();
//        if (deptIds == null || deptIds.isEmpty()) {
//            return R.failed("请选择部门可见范围");
//        }
        Integer type = prodEntity.getType();
        if (StrUtil.isEmpty(prodEntity.getOnTime()))
            prodEntity.setOnTime(null);
        if (StrUtil.isEmpty(prodEntity.getStartTime()))
            prodEntity.setStartTime(null);
        if (StrUtil.isEmpty(prodEntity.getEndTime()))
            prodEntity.setEndTime(null);
        if (type != null && type.equals(ProductGroupEnum.ACTIVITY.getCode())) {
            prodEntity.setOnTime(null);
        }
        prodEntity.setState(1);

        return R.ok(prodService.updateProd(prodEntity, deptIds));
    }

    @SysLog("产品上下架")
    @PutMapping("/upDownProd")
    @ApiOperation(value = "产品上下架")
    public R upDownProd(Integer prodId, Integer state) {
        if (state.equals(1)) {
            return R.ok(prodService.update(
                    Wrappers.<ProdEntity>lambdaUpdate()
                            .set(ProdEntity::getState, state)
                            .eq(ProdEntity::getId, prodId)
            ));
        } else if (state.equals(2)) {
            ProdEntity entity = prodService.getById(prodId);
            checkEndTime(entity.getEndTime());
            if (entity.getState() != null && entity.getState().equals(0))
                return R.failed("您要上架的产品当前状态为0-未编辑，请编辑后再发布");
            return R.ok(prodService.update(
                    Wrappers.<ProdEntity>lambdaUpdate()
                            .set(ProdEntity::getState, state)
                            .set(ProdEntity::getOnTime, LocalDateTime.now())
                            .eq(ProdEntity::getId, prodId)
            ));
        }
        return R.failed();
    }

    @SysLog("产品发布/上架")
    @PutMapping("/publish")
    @ApiOperation(value = "产品发布/上架")
    public R publish(Integer prodId) {
        ProdEntity entity = prodService.getById(prodId);
        checkEndTime(entity.getEndTime());
        if (entity.getState() != null && entity.getState().equals(0))
            return R.failed("您要发布/上架的产品当前状态为0-未编辑，请编辑后再发布/上架");
        return R.ok(prodService.update(
                Wrappers.<ProdEntity>lambdaUpdate()
                        .set(ProdEntity::getState, 3)
                        .set(ProdEntity::getOnTime, LocalDateTime.now())
                        .eq(ProdEntity::getId, prodId)
        ));
    }

    @SysLog("产品下架/撤销")
    @PutMapping("/down")
    @ApiOperation(value = "产品下架/撤销")
    public R down(Integer prodId) {
        return R.ok(prodService.update(
                Wrappers.<ProdEntity>lambdaUpdate()
                        .set(ProdEntity::getState, 1)
                        .set(ProdEntity::getOnTime, null)
                        .eq(ProdEntity::getId, prodId)
        ));
    }

    @SysLog("活动开关")
    @PutMapping("/open-close")
    @ApiOperation(value = "活动开关")
    public R openClose(Integer prodId, Integer state) {
        return R.ok(prodService.update(
                Wrappers.<ProdEntity>lambdaUpdate()
                        .set(ProdEntity::getState, state)
                        .eq(ProdEntity::getId, prodId)
        ));
    }

    @SysLog("精选/非精选")
    @PutMapping("/chose")
    @ApiOperation(value = "精选/非精选")
    public R chose(Integer prodId, Integer status) {
        return R.ok(prodService.update(
                Wrappers.<ProdEntity>lambdaUpdate()
                        .set(ProdEntity::getStatus, status)
                        .eq(ProdEntity::getId, prodId)
        ));
    }

    // 只有2-活动、4-贷款、5-信用卡可删除
    @SysLog("删除产品-活动/贷款/信用卡")
    @DeleteMapping
    @ApiOperation(value = "删除产品")
    public R deleteProd(Integer prodId) {
        ProdEntity entity = prodService.getById(prodId);
        Integer type = entity.getType();
        if (type == null || (
                !type.equals(ProductGroupEnum.ACTIVITY.getCode())
                        && !type.equals(ProductGroupEnum.LOAN.getCode())
                        && !type.equals(ProductGroupEnum.CREDITCARD.getCode())
        ))
            return R.failed("产品类型不在可删除的产品类型范围[2-活动、4-贷款、5-信用卡]内");
        return R.ok(prodService.removeProd(prodId));
    }


    @Inner
    @SysLog("定时关闭/下架过期活动/产品")
    @GetMapping("/synclose")
    @ApiOperation(value = "定时关闭/下架过期活动/产品")
    public void synClose() {
        onSyncClose();
    }

    @Async
    public void onSyncClose() {
        DateTime now = new DateTime();
        prodService.update(
                Wrappers.<ProdEntity>lambdaUpdate()
                .set(ProdEntity::getState, 1)
                .lt(ProdEntity::getEndTime, now)
        );
    }

    private void checkEndTime(String endTimeStr) {
        if (endTimeStr == null)
            return ;
        try {
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            Date date = sdf1.parse(endTimeStr);
            long endTime = date.getTime();
            if (endTime < System.currentTimeMillis()) {
                throw new CheckedException("产品结束时间/到期日期小于当前时间，请修改后再上架/开启");
            }
        } catch(ParseException e) {
            e.printStackTrace();
        }
    }

}
